<script setup lang="ts">
import { ref, reactive, computed } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import {
  Row,
  Col,
  Table,
  Pagination,
  Button,
  Empty,
  Spin,
  Select,
  Form,
  FormItem,
  Modal,
} from 'ant-design-vue';
import type { RuleObject } from 'ant-design-vue/es/form';
import { repositoryList } from '#/api/knowledge/repository';
import { educationTitleList } from '#/api/knowledge/repository/education';
import type { RepositoryVO } from '#/api/knowledge/repository/model';
import type { EducationVO } from '#/api/knowledge/repository/education/model';
import { useBeforeCloseDiff } from '#/utils/popup';
import {
  planConfigUpdate,
  planConfigInfo,
} from '#/api/healthPlan/config/planConfig';
import type {
  PlanConfigForm,
  KnowledgeConfigForm,
  PlanConfigVO,
} from '#/api/healthPlan/config/planConfig/model';
import type { SelectValue } from 'ant-design-vue/es/select';

const emit = defineEmits<{ reload: [] }>();

const title = '配置常规宣教';
const taskData = ref<PlanConfigVO | null>(null);

// --- 表单数据 ---
const getDefaultValues = (): Partial<KnowledgeConfigForm> & {
  knowledgeBaseId?: string;
  selectedArticleIds?: (string | number)[];
} => ({
  // taskName: '',
  knowledgeBaseId: undefined,
  selectedArticleIds: [],
});

const formData = ref(getDefaultValues());

const formRules = computed<
  Partial<Record<keyof KnowledgeConfigForm, RuleObject[]>>
>(() => {
  return {
    knowledgeBaseId: [{ required: true, message: '请选择知识库' }],
    selectedArticleIds: [
      {
        type: 'array',
        required: true,
        min: 1,
        message: '请至少选择一篇宣教文章',
      },
    ],
  };
});

const { validate, validateInfos, resetFields } = Form.useForm(
  formData,
  formRules,
);

// --- 知识库选择（分页） ---
const kb = reactive({
  list: [] as RepositoryVO[],
  page: 1,
  pageSize: 20,
  total: 0,
  loading: false,
  loadingMore: false,
});

// --- 知识文章选择（分页表格 + 已选列表） ---
const articles = reactive({
  list: [] as EducationVO[],
  page: 1,
  pageSize: 5,
  total: 0,
  loading: false,
});
const selectedArticles = ref<Record<string | number, EducationVO>>({});
const selectedRowKeys = computed(() => Object.keys(selectedArticles.value));

const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff(
  {
    initializedGetter: () => JSON.stringify(formData.value),
    currentGetter: () => JSON.stringify(formData.value),
  },
);

const [BasicModal, modalApi] = useVbenModal({
  class: 'w-[1000px]',
  onBeforeClose,
  onClosed: handleClosed,
  onConfirm: handleConfirm,
  onOpenChange: async (isOpen) => {
    if (!isOpen) return;
    modalApi.modalLoading(true);
    const record = modalApi.getData();
    // 先加载知识库
    await fetchKnowledgeBases();
    // 获取任务配置
    taskData.value = await planConfigInfo(record.id);
    const taskConfig = taskData.value.taskConfig as KnowledgeConfigForm;
    // 设置知识库
    formData.value.knowledgeBaseId = taskConfig.knowledgeBaseId;
    // 加载该知识库文章列表
    await fetchArticles();
    // 回显已选文章
    if (taskConfig.educationIds?.length) {
      const res = await educationTitleList({
        knowledgeBaseId: taskConfig.knowledgeBaseId,
        pageNum: 1,
        pageSize: taskConfig.educationIds.length,
        ids: taskConfig.educationIds.join(','), // 后端接口支持按 ids 查询
      });
      selectedArticles.value = res.rows.reduce(
        (acc: Record<string, EducationVO>, cur) => {
          acc[cur.id] = cur;
          return acc;
        },
        {},
      );
      formData.value.selectedArticleIds = Object.keys(selectedArticles.value);
    }
    await markInitialized();
    modalApi.modalLoading(false);
  },
});

// --- 数据获取 ---
async function fetchKnowledgeBases(page = 1, isLoadMore = false) {
  kb.loading = !isLoadMore;
  kb.loadingMore = isLoadMore;
  try {
    const res = await repositoryList({ pageNum: page, pageSize: kb.pageSize,baseType: 'EDUCATION', });
    kb.list = page === 1 ? res.rows : [...kb.list, ...res.rows];
    kb.total = res.total;
    kb.page = page;
  } finally {
    kb.loading = false;
    kb.loadingMore = false;
  }
}

async function fetchArticles(page = 1) {
  if (!formData.value.knowledgeBaseId) return;
  articles.loading = true;
  try {
    const res = await educationTitleList({
      knowledgeBaseId: formData.value.knowledgeBaseId,
      pageNum: page,
      pageSize: articles.pageSize,
    });
    articles.list = res.rows;
    articles.total = res.total;
    articles.page = page;
  } finally {
    articles.loading = false;
  }
}

// --- UI交互 ---
function handleKbScroll(e: any) {
  const { target } = e;
  if (target.scrollTop + target.clientHeight >= target.scrollHeight - 10) {
    if (kb.page * kb.pageSize < kb.total && !kb.loadingMore) {
      fetchKnowledgeBases(kb.page + 1, true);
    }
  }
}

const handleKnowledgeBaseChange = (value: SelectValue) => {
  if (!value) {
    // 清空文章列表和选中项
    articles.list = [];
    articles.total = 0;
    articles.page = 1;
    selectedArticles.value = {};
    formData.value.selectedArticleIds = [];
    return;
  }
  value = value.toString();
  if (
    formData.value.knowledgeBaseId &&
    formData.value.knowledgeBaseId !== value &&
    selectedRowKeys.value.length
  ) {
    // 已选文章且切换知识库，提示确认
    Modal.confirm({
      title: '切换知识库',
      content: '切换知识库会清空已选文章，是否继续？',
      okText: '确认',
      cancelText: '取消',
      onOk() {
        // 清空已选文章
        selectedArticles.value = {};
        formData.value.selectedArticleIds = [];
        // 更新知识库并加载文章
        formData.value.knowledgeBaseId = value;
        articles.list = [];
        articles.total = 0;
        articles.page = 1;
        fetchArticles(1);
      },
      onCancel() {
        // 取消切换，恢复之前选择的知识库
        formData.value.knowledgeBaseId = formData.value.knowledgeBaseId;
      },
    });
  } else {
    // 正常选择
    formData.value.knowledgeBaseId = value;
    articles.list = [];
    articles.total = 0;
    articles.page = 1;
    fetchArticles(1);
  }
};

const rowSelection = computed(() => ({
  preserveSelectedRowKeys: true,
  selectedRowKeys: selectedRowKeys.value,
  onChange: (keys: (string | number)[], rows: EducationVO[]) => {
    const currentPageIds = articles.list.map((item) => item.id);
    rows.forEach((row) => {
      if (!selectedArticles.value[row.id]) {
        selectedArticles.value[row.id] = row;
      }
    });
    currentPageIds.forEach((id) => {
      if (!keys.includes(id) && selectedArticles.value[id]) {
        delete selectedArticles.value[id];
      }
    });
    formData.value.selectedArticleIds = Object.keys(selectedArticles.value);
  },
}));

function removeSelectedArticle(id: string | number) {
  delete selectedArticles.value[id];
  formData.value.selectedArticleIds = Object.keys(selectedArticles.value);
}

async function handleConfirm() {
  try {
    modalApi.modalLoading(true);
    await validate();
    const payload: Partial<PlanConfigForm> = {
      id: taskData.value!.id,
      // taskName: formData.value.taskName,
      taskType: 'EDUCATION',
      taskConfig: {
        knowledgeBaseId: formData.value.knowledgeBaseId,
        educationIds: Object.keys(selectedArticles.value),
      },
      triggerType: taskData.value!.triggerType,
      triggerConfig: taskData.value!.triggerConfig,
    };
    await planConfigUpdate(payload);
    resetInitialized();
    emit('reload');
    modalApi.close();
  } catch (err) {
    console.log('表单校验失败', err);
  } finally {
    modalApi.modalLoading(false);
  }
}

function handleClosed() {
  resetFields();
  Object.assign(kb, {
    list: [],
    page: 1,
    total: 0,
  });
  Object.assign(articles, {
    list: [],
    page: 1,
    total: 0,
  });
  selectedArticles.value = {};
  resetInitialized();
}
</script>

<template>
  <BasicModal :title="title">
    <Form :model="formData" layout="vertical">
      <!-- <FormItem label="方案名称" v-bind="validateInfos.taskName">
        <Input v-model:value="formData.taskName" placeholder="请输入方案名称" />
      </FormItem> -->
      <FormItem label="知识库" v-bind="validateInfos.knowledgeBaseId">
        <Select
          v-model:value="formData.knowledgeBaseId"
          placeholder="请选择知识库"
          allow-clear
          show-search
          :filter-option="false"
          :loading="kb.loading"
          @change="handleKnowledgeBaseChange"
          @dropdown-visible-change="
            (open) => open && !kb.list.length && fetchKnowledgeBases()
          "
          @popup-scroll="handleKbScroll"
        >
          <Select.Option
            v-for="item in kb.list"
            :key="item.id"
            :value="item.id"
          >
            {{ item.name }}
          </Select.Option>
          <Select.Option v-if="kb.loadingMore" disabled value="loading">
            <div class="text-center"><Spin size="small" /></div>
          </Select.Option>
        </Select>
      </FormItem>
      <FormItem label="宣教内容" v-bind="validateInfos.selectedArticleIds">
        <Row :gutter="16">
          <Col :span="14">
            <div class="rounded border p-2">
              <p class="mb-2 font-bold">可选知识</p>
              <Table
                :columns="[
                  { title: '文章标题', dataIndex: 'title', width: '80%' },
                  // { title: '作者', dataIndex: 'authorName', width: '20%' },
                  // { title: '发布时间', dataIndex: 'publishTime', width: '25%' },
                ]"
                :data-source="articles.list"
                :pagination="false"
                :row-selection="rowSelection"
                :loading="articles.loading"
                row-key="id"
                size="small"
              />
              <Pagination
                v-if="articles.total > 0"
                v-model:current="articles.page"
                :page-size="articles.pageSize"
                :total="articles.total"
                size="small"
                @change="(page) => fetchArticles(page)"
                class="mt-2 text-right"
              />
            </div>
          </Col>
          <Col :span="10">
            <div class="h-full rounded border p-2">
              <p class="mb-2 font-bold">
                已选知识 ({{ selectedRowKeys.length }})
              </p>
              <div
                v-if="selectedRowKeys.length === 0"
                class="flex h-full items-center justify-center"
              >
                <Empty description="请从左侧选择" />
              </div>
              <div v-else class="selected-list">
                <div
                  v-for="item in selectedArticles"
                  :key="item.id"
                  class="selected-item"
                >
                  <span class="flex-1 truncate pr-2">{{ item.title }}</span>
                  <Button
                    type="link"
                    danger
                    size="small"
                    @click="removeSelectedArticle(item.id)"
                  >
                    移除
                  </Button>
                </div>
              </div>
            </div>
          </Col>
        </Row>
      </FormItem>
    </Form>
  </BasicModal>
</template>

<style scoped>
.selected-list {
  max-height: 300px;
  overflow-y: auto;
}
.selected-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 8px;
  border-radius: 4px;
  margin-bottom: 4px;
  background-color: #f5f5f5;
}
</style>
